package org.hdl.anima.backend;

import org.hdl.anima.Application;
import org.hdl.anima.handler.ServiceHandlers;
import org.hdl.anima.message.CloseBackendSessionReq;
import org.hdl.anima.message.CreateBackendSessionReq;
import org.hdl.anima.message.CreateLocalSessionReq;
import org.hdl.anima.message.CreateLocalSessionResp;
import org.hdl.anima.message.IResponse;
import org.hdl.anima.message.RequestWrap;
import org.hdl.anima.session.BackendSession;
import org.hdl.anima.session.BackendSessionMgr;
import org.hdl.anima.session.LocalSession;
import org.hdl.anima.session.LocalSessionMgr;
import org.hdl.anima.transport.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 
 * @author qiuhd
 * @since  2014年8月15日
 */
public class BackendHandler {

	private static final Logger LOGGER = LoggerFactory.getLogger(BackendHandler.class);
	private final Channel channel ;
	private final Application application;
	private volatile boolean sessionCreated = false;
	private volatile LocalSession localSession ;
	private final ServiceHandlers serverHandlers;
	private BackendSessionMgr backendSessionMgr ;
	
	public BackendHandler(Application app,Channel channel) {
		this.application = app;
		this.channel = channel;
		this.serverHandlers = application.getMoulde(ServiceHandlers.class);
		this.backendSessionMgr = application.getMoulde(BackendSessionMgr.class);
	}
	
	public void process(Object message) throws Exception {
		if (!sessionCreated) {
			boolean createSession = message instanceof CreateLocalSessionReq ? true : false;
			if (createSession) {
				CreateLocalSessionReq req = (CreateLocalSessionReq) message;
				String rsid =  req.getRsid();
				localSession = LocalSessionMgr.getInstance().createSession(rsid, channel);
				LOGGER.debug("Create local session successful, the remote server id {}",rsid);
				IResponse response = CreateLocalSessionResp.create(req.getRsid());
				response.setRequest(req);
				this.sessionCreated = true;
				//发送创建响应消息响应
				localSession.send(response);
			}else {
				//第一个消息不是创建session,关闭通道 
				channel.close();
				LOGGER.debug("Failed to process messsage,cause : the channel first message is not create session message");
			}
		} else {
			hanlder(message);
		}
	}
	
	private void hanlder(Object message) throws Exception {
		if (message instanceof CreateBackendSessionReq) {
			CreateBackendSessionReq createSessionReq = (CreateBackendSessionReq)message;
			backendSessionMgr.createSession(localSession.getServerId(), createSessionReq.getIdentity(),
					createSessionReq.getRemoteAddress(), createSessionReq.getRemotePort(), 
					createSessionReq.getRemoteAddress(), createSessionReq.getLocalPort());
			
		}else if (message instanceof CloseBackendSessionReq) {
			CloseBackendSessionReq closeSessionReq = (CloseBackendSessionReq)message;
			BackendSession session =  backendSessionMgr.getSession(closeSessionReq.getIdentity());
			session.close();
		}else if (message instanceof RequestWrap) {
			RequestWrap requestWrap = (RequestWrap)message;
			int identity = requestWrap.getsId();
			BackendSession backendSession = backendSessionMgr.getSession(identity);
			if (backendSession == null) {
				//TODO 通知连接服务器关闭客户端连接
				LOGGER.error("Failed to handle message,cause backend session already closed!");
				return ;
			}
			serverHandlers.process(requestWrap.getMessage(), backendSession);
		}
	}
	
	public LocalSession getLocalSession() {
		return this.localSession;
	}
}

